package com.jsyso.jsyso.util;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;

import com.jsyso.jsyso.lang.JStringUtils;

/**
 * Map工具类
 * @author janjan, xujian_jason@163.com
 *
 */
public abstract class Maps {

	/**
	 * Map过滤
	 * @param map
	 * @param filter
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static <K, V> HashMap<K, V> filter(final Map<? extends K, ? extends V> map, 
			Filter<K> filter) {
		final HashMap<K, V> newMap = new HashMap<K, V>();
		if(map != null && !map.isEmpty()) {
			Set<? extends K> keys = map.keySet();
			for(Object k : keys) {
				K key = (K)k;
				Object value = map.get(key);
				if(filter == null || filter.apply(key)) {
					newMap.put(key, (V)value);
				}
			}
		}
		return newMap;
	}
	
	/**
	 * 过滤并拼接values
	 * @param map
	 * @param filter
	 * @param separator
	 * @return
	 */
	public static <K, V> String joinValues(final Map<? extends K, ? extends V> map, 
			Filter<K> filter, final String separator) {
		return StringUtils.join(filter(map, filter).values(), separator);
	}
	
	public static boolean containsKeys(final Map<?, ?> map, final Object[] keys) {
		if(keys == null || keys.length == 0 
				|| map == null || map.isEmpty()) {
			return false;
		}
		for(Object key : keys) {
			if(map.containsKey(key)) {
				return true;
			}
		}
		return false;
	}
	
	/**
	 * JavaBean 转 JsMap
	 * @param obj 对象
	 * @param openDbName 是否开启数据库命名（英文下划线分隔，例如：sys_user、cms_article）
	 * @param separator 数据库分隔符
	 * @return
	 */
	public static <T> JsMap beanToJsMap(T obj, boolean openDbName, char separator) {
		JsMap map = JsMap.create();
		if(obj == null) {
			return map;
		}
		Method[] ms = obj.getClass().getMethods();
		for(Method m : ms) {
			String name = "";
			if (name.startsWith("get")) {
				name = name.substring(3);
            } else if (name.startsWith("is")) {
            	name = name.substring(2);
            }
			// 只需要 Object getName()
			if (name.length() == 0 || "Class".equals(name) 
					|| m.getParameterTypes().length > 0 
					|| m.getReturnType() == void.class) {
				continue ;
			}
			try {
				// 首字母小写
				name = Character.toLowerCase(name.charAt(0)) + name.substring(1);
				// 是否转换成数据库命名
				name = openDbName ? JStringUtils.toUnderScoreCase(name, separator) : name;
				Object value = m.invoke(obj);
				if(value == null) {
					continue ;
				}
				if(value instanceof Boolean) {
					value = ((Boolean)value) ? 1 : 0;
				}
				map.put(name, value);
			} catch (Exception e) {
				throw new RuntimeException(e.getMessage(), e);
			}
		}
		return map;
	}
	
	public static <T> JsMap beanToJsMap(T obj) {
		return beanToJsMap(obj, true, JStringUtils.DEFAULT_CAMEL_SEPARATOR);
	}
	
}
